home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS in a Box 7
/
BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso
/
Files
/
Tele
/
C
/
Comet2.1.3.cpt
/
Comet
/
gethost.c
< prev
next >
Wrap
Text File
|
1991-09-25
|
17KB
|
790 lines
/*
Copyright Cornell University 1986. All rights are reserved.
gethost.c contains the dialog used to get a host name/address from
the user and maintain the associated database.
*/
#include <em.h>
#include <list.h>
#include <config.h>
#include <h19.h>
#include <resdefs.h>
#include <menudefs.h>
#include <net.h> /* merged TCP */
#ifdef DUALTCP
#endif
#ifdef MACTCP
#include <MacTCPCommonTypes.h>
#include <AddressXlation.h>
#else
#include <tcp.h>
#include <tcpdefs.h>
#endif
extern char * malloc();
extern unsigned long mtdnresolve();
long nameresolved;
#define LASTHOSTID 0
extern char * index();
/* See permission and disclaimer notice in file "notice.h" */
/* resolve_name.c */
/* Resolve a host name into an internet address. Three name formats are
* accepted:
* 1) A character string host name
* 2) An octal host number, in the form:
* <net>,<subnet>,<rsd>,<host>
* or a decimal host number, in the form:
* <net>.<subnet>.<rsd>.<host>
* Any of the <net>, <subnet>, and <rsd> may be left blank or left out
* entirely; they default to the local net/subnet.
* 3) A thirty-two bit hex number, preceeded by a '#', which is used
* without interpretation as the host number.
* If a character string name is supplied, it is first looked up in a
* local host table. If it is not found there, the routine goes off to
* internet name servers to try to resolve the name.
*
* The following routines are included in this file:
* resolve_name Resolve a name as specified above
* gethmch Parse a hex machine address specification
* getomch Parse an octal machine address specification
* The routines which use the internet name server are in the file
* name_user.c.
*/
#define INSZ 4
extern char *index();
/* Resolve foreign host internet address
* Scan table of host names and nicknames.
* For each name, see if our string is a prefix. If so, keep checking -
* could be ambiguous.
* If ambiguous, return 0.
* When find no matches, try internet name servers.
*
* Arguments:
*/
resolve_name(name, hsockp)
char *name;
struct hostsock * hsockp;
{
char tname[100];
char taddr[100];
unsigned int port;
int hostconnact;
int sockargs;
int dotargs;
short dotseen = FALSE;
unsigned char * namep;
if (strlen(name) == 0) {
error("No address given");
return(-1);
}
if ((name[0] >= '0') && (name[0] <= '9')) {
/* leading numeral indicates an internet address using dot notation */
if (getdmch(name, hsockp)) {
error(badaddress);
return(-1);
}
}
else if (name[0] == '#') {
/* leading '#' indicates hex address */
if (gethmch(name, hsockp)) {
error(badaddress);
return(-1);
}
}
else if (emdp->conntype == CONN_MACTCP) {
/* a string, hand it to the domain name resolver */
/* first parse the socket number which is "..300" format */
hsockp->port = TELNETSOCK;
sockargs = sscanf(name, "%s", &tname[0]);
dotargs = 0;
namep = &tname[0];
while (*namep) {
if (*namep == '.') {
if (dotseen) {
/* double dot is end of host name, beginning of socket */
--namep;
*namep = '\0'; /* terminate the string at first dot */
namep += 2; /* skip the dots */
dotargs = sscanf(namep, "%d;%d", &port, &hostconnact);
}
dotseen = TRUE;
}
else
dotseen = FALSE;
namep++;
}
/* we presume this is an IP Domain Name if it doesn't match
any of the above constants, so we try the DNR */
if ((hsockp->u.addr = mtdnresolve(&tname[0])) == 0)
return(-1);
if (hsockp->u.addr == -1)
/* prevent attempts to open a session with the broadcast address -1 ... */
return(-1);
/* now set the socket and id portions */
if (dotargs >= 1 && port != 0)
hsockp->port = port;
else
hsockp->port = TELNETSOCK;
if (dotargs == 2)
hsockp->hostconnact = hostconnact;
else
hsockp->hostconnact = -1;
}
else {
/* old TCP can't handle DNR */
error("Cornell TCP can't resolve domain names");
hsockp->u.addr = -1L;
return(-1);
}
return(0);
}
/* Parse foreign host number input as hex string */
gethmch(name, hsockp)
register char *name;
struct hostsock * hsockp;
{
register char *tmp;
register int i;
union {
char bytes[INSZ];
long name;
} addr;
tmp = &name[1];
for (i = 0; i < 8; i++) {
if ((*tmp >= '0') && (*tmp <= '9'))
*tmp++ -= '0';
else if ((*tmp >= 'A') && (*tmp <= 'Z'))
*tmp++ -= ('A' - 10);
else if ((*tmp >= 'a') && (*tmp <= 'z'))
*tmp++ -= ('a' - 10);
else {
hsockp->u.addr = -1L;
return(-1);
}
}
if (*tmp != 0) {
hsockp->u.addr = -1L;
return(-1);
}
tmp = &name[1];
for (i = 0; i < INSZ; i++)
addr.bytes[i] = ((*tmp++ << 4) + *tmp++);
hsockp->u.addr = addr.name;
return(0);
}
/* Parse foreign host number input as decimal string, placing host socket in hsockp */
getdmch(name, hsockp)
char *name;
struct hostsock * hsockp;
{
unsigned int addr[4];
unsigned int port;
int hostconnact;
register char thechar;
register char * tempp;
int sockargs;
int ipargs;
int count;
int addrb; /* counter for accessing the bytes in the addr backwards */
sockargs = 0;
hsockp->u.addr = rnet->ip_addr;
hsockp->port = 0;
hsockp->hostconnact = 0;
/* reset hostsock struct */
/* if a ".." is in the string, a socket comes after it;
interpret the socket as a decimal #
if a ';' occurs in the address, it indicates a string ID for connect
actions
*/
ipargs = sscanf(name, "%d.%d.%d.%d", &addr[0], &addr[1],
&addr[2], &addr[3]);
for (count = ipargs, addrb = 3; --count >= 0; --addrb) {
/* spot bad addresses for 1-4 */
if (addr[count] < 0 || addr[count] > 256) {
hsockp->u.addr = -1L;
return(-1);
}
hsockp->u.bytes[addrb] = addr[count];
}
/* we got the IP address, get the rest */
sockargs = sscanf(name, "%d.%d.%d.%d..%d;%d", &addr[0], &addr[1],
&addr[2], &addr[3], &port, &hostconnact);
/* now set the socket as desired */
if (sockargs >= 5 && port != 0)
hsockp->port = port;
else
hsockp->port = TELNETSOCK;
if (sockargs == 6)
hsockp->hostconnact = hostconnact;
else
hsockp->hostconnact = -1;
return(0);
}
#ifdef MACTCP
extern unsigned long getmyA5();
pascal void resolved();
unsigned long mtdnresolve(tname)
char * tname; /* hostname */
{
struct hostInfo hostinfo;
if (!macipopen) {
/* open the MacTCP driver if not open TODO this won't handle async */
if (macip_init())
return(-1);
}
/* open the DNR */
if (OpenResolver(NULL)) {
error("Can't open MacTCP Domain Name Resolver");
return(-1);
}
/* call the DNR */
/*
char * mtcpresolvewait = "\r\r Getting host address from domain name server...";
fillwindow(COPYWINDOW, mtcpresolvewait, (long) strlen(mtcpresolvewait), systemFont, 12, (long) -1);
for some reason this induces mactcp to crash!
*/
SetCursor(*GetCursor(watchCursor));
/* put up a watch cursor to show this may take some time */
nameresolved = 0;
StrToAddr(tname, &hostinfo, resolved, NULL);
while (!nameresolved) {
short thechar;
EventRecord evt;
/* check to see if the user wants to abort, because mactcp's dnr
sometimes hangs... */
GetNextEvent(keyDownMask|autoKeyMask, &evt);
if (evt.what == keyDown || evt.what == autoKey) {
thechar = evt.message & 0xff;
if (evt.modifiers & cmdKey) {
if (thechar == '.') {
error("Interrupting the MacTCP domain name resolver may be hazardous; you should probably reboot your machine");
break;
}
}
}
bkrd_service();
}
SetCursor(&arrow);
/*
fillwindclose();
*/
CloseResolver();
if (nameresolved != 1) {
switch (nameresolved) {
case nameSyntaxErr:
error("MacTCP resolver: invalid name syntax");
break;
case cacheFault:
error("MacTCP resolver: no answer from nameserver");
/* error("MacTCP resolver: cache fault"); */
break;
case noResultProc:
error("MacTCP resolver: no result proc");
break;
case noNameServer:
error("MacTCP resolver: can't find name server");
break;
case authNameErr:
error("MacTCP resolver: auth. name error");
break;
case noAnsErr:
error("MacTCP resolver: no answer from nameserver");
break;
case dnrErr:
error("MacTCP resolver: error in domain name resolver");
break;
}
}
return(hostinfo.addr[0]);
}
/* DNR.c - DNR library for MPW
(c) Copyright 1988 by Apple Computer. All rights reserved
*/
#include <errors.h>
#define OPENRESOLVER 1
#define CLOSERESOLVER 2
#define STRTOADDR 3
#define ADDRTOSTR 4
#define ENUMCACHE 5
#define ADDRTONAME 6
#define HINFO 7
#define MXINFO 8
Handle codeHndl = NULL;
OSErrProcPtr dnr = NULL;
#define OLDDNR
#ifdef OLDDNR
/* OpenOurRF is called to open the MacTCP driver resources */
short OpenOurRF()
{
HPrmBlkRec fi;
Str255 filename;
#define ZBEN
#ifdef ZBEN /* ! */
short savevol; /* ! */
OSErr status; /* ! */
extern SysEnvRec environs;
#endif /* ! */
fi.ioCompletion = NULL;
fi.ioNamePtr = &filename;
fi.ioVRefNum = environs.sysVRefNum;
fi.u.hfp.ioDirID = 0;
fi.u.hfp.ioFDirIndex = 1;
while (PBHGetFInfo(&fi, (Boolean) FALSE) == noErr) {
/* scan system folder for driver resource files of specific type & creator */
if (fi.u.hfp.ioFlFndrInfo.fdType == 'cdev' &&
fi.u.hfp.ioFlFndrInfo.fdCreator == 'mtcp') {
/* found the MacTCP driver file */
#ifdef ZBEN
/* a fix courtesy of usenet to the DNR,
which will fail to get the resource it wants
if it's not on the main Volume (another PMSP-related
problem
*/
/* ! */
GetVol((StringPtr) NULL,&savevol); /* ! */
SetVol((StringPtr) NULL,environs.sysVRefNum); /* ! */
status = OpenResFile(&filename); /* ! */
SetVol((StringPtr) NULL,savevol); /* ! */
return(status); /* ! */
#else /* ! */
return(OpenResFile(&filename));
#endif
}
/* check next file in system folder */
fi.u.hfp.ioFDirIndex++;
fi.u.hfp.ioDirID = 0;
}
return(-1);
}
OSErr OpenResolver(fileName)
char *fileName;
{
short refnum;
OSErr rc;
if (dnr != NULL)
/* resolver already loaded in */
return(noErr);
/* open the MacTCP driver to get DNR resources. Search for it based on
creator & type rather than simply file name */
refnum = OpenOurRF();
/* ignore failures since the resource may have been installed in the
System file if running on a Mac 512Ke */
/* load in the DNR resource package */
codeHndl = GetIndResource('dnrp', 1);
if (codeHndl == NULL) {
/* can't open DNR */
return(ResError());
}
DetachResource(codeHndl);
if (refnum != -1) {
CloseResFile(refnum);
}
/* lock the DNR resource since it cannot be reloated while opened */
HLock(codeHndl);
dnr = (OSErrProcPtr) *codeHndl;
/* call open resolver */
rc = (*dnr)((long) OPENRESOLVER, fileName);
if (rc != noErr) {
/* problem with open resolver, flush it */
HUnlock(codeHndl);
DisposHandle(codeHndl);
dnr = NULL;
}
return(rc);
}
#else
/* use the stuff provided with MacTCP 1.1B1, which adds Sys 7.0-stuff */
TrapType GetTrapType(theTrap)
unsigned long theTrap;
{
if (BitAnd(theTrap, 0x0800) > 0)
return(ToolTrap);
else
return(OSTrap);
}
Boolean TrapAvailable(trap)
unsigned long trap;
{
TrapType trapType = ToolTrap;
unsigned long numToolBoxTraps;
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
numToolBoxTraps = 0x200;
else
numToolBoxTraps = 0x400;
trapType = GetTrapType(trap);
if (trapType == ToolTrap) {
trap = BitAnd(trap, 0x07FF);
if (trap >= numToolBoxTraps)
trap = _Unimplemented;
}
return(NGetTrapAddress(trap, trapType) != NGetTrapAddress(_Unimplemented, ToolTrap));
}
short GetCPanelFolder()
{
short vRefNum = 0;
long dirID = 0;
SysEnvRec info;
Boolean hasFolderMgr = (Boolean) FALSE;
long feature;
short wdRef;
if (TrapAvailable(_GestaltDispatch))
if (Gestalt(gestaltFindFolderAttr, &feature) == noErr)
hasFolderMgr = (Boolean) TRUE;
if (!hasFolderMgr) {
SysEnvirons(1, &info);
return(info.sysVRefNum);
}
else {
if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, &vRefNum, &dirID) != noErr)
return(0);
if (OpenWD(vRefNum, dirID, 'dnrp', &wdRef) == noErr)
return(wdRef);
else
return(0);
}
}
/* OpenOurRF is called to open the MacTCP driver resources */
short OpenOurRF()
{
ParamBlockRec fi;
Str255 filename;
short vRefNum;
vRefNum = GetCPanelFolder();
fi.fileParam.ioCompletion = NULL;
fi.fileParam.ioNamePtr = &filename;
fi.fileParam.ioVRefNum = vRefNum;
fi.fileParam.ioFDirIndex = 1;
while (PBGetFInfo(&fi, (Boolean) FALSE) == noErr) {
/* scan system folder for driver resource files of specific type & creator */
if (fi.fileParam.ioFlFndrInfo.fdType == 'cdev' &&
fi.fileParam.ioFlFndrInfo.fdCreator == 'ztcp') {
/* found the MacTCP driver file */
return(OpenRFPerm(&filename, vRefNum, fsRdPerm));
}
/* check next file in system folder */
fi.fileParam.ioFDirIndex++;
}
return(-1);
}
OSErr OpenResolver(fileName)
char *fileName;
{
short refnum;
OSErr rc;
if (dnr != NULL)
/* resolver already loaded in */
return(noErr);
/* open the MacTCP driver to get DNR resources. Search for it based on
creator & type rather than simply file name */
refnum = OpenOurRF();
/* ignore failures since the resource may have been installed in the
System file if running on a Mac 512Ke */
/* load in the DNR resource package */
codeHndl = GetIndResource('dnrp', 1);
if (codeHndl == NULL) {
/* can't open DNR */
return(ResError());
}
DetachResource(codeHndl);
if (refnum != -1) {
CloseWD(refnum);
CloseResFile(refnum);
}
/* lock the DNR resource since it cannot be reloated while opened */
HLock(codeHndl);
dnr = (OSErrProcPtr) *codeHndl;
/* call open resolver */
rc = (*dnr)((long) OPENRESOLVER, fileName);
if (rc != noErr) {
/* problem with open resolver, flush it */
HUnlock(codeHndl);
DisposHandle(codeHndl);
dnr = NULL;
}
return(rc);
}
#endif
OSErr CloseResolver()
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
/* call close resolver */
(void) (*dnr)((long) CLOSERESOLVER);
/* release the DNR resource package */
HUnlock(codeHndl);
DisposHandle(codeHndl);
dnr = NULL;
return(noErr);
}
OSErr StrToAddr(hostName, rtnStruct, resultproc, userDataPtr)
char *hostName;
struct hostInfo *rtnStruct;
long resultproc;
char *userDataPtr;
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
return((*dnr)((long) STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
}
OSErr AddrToStr(addr, addrStr)
unsigned long addr;
char *addrStr;
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
(*dnr)((long) ADDRTOSTR, addr, addrStr);
return(noErr);
}
OSErr EnumCache(resultproc, userDataPtr)
long resultproc;
char *userDataPtr;
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
return((*dnr)((long) ENUMCACHE, resultproc, userDataPtr));
}
OSErr AddrToName(addr, rtnStruct, resultproc, userDataPtr)
unsigned long addr;
struct hostInfo *rtnStruct;
long resultproc;
char *userDataPtr;
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
return((*dnr)((long) ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
}
OSErr HInfo(hostName, returnRecPtr, resultProc, userDataPtr)
char *hostName;
struct returnRec *returnRecPtr;
long resultProc;
char *userDataPtr;
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
return((*dnr)((long) HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
}
OSErr MXInfo(hostName, returnRecPtr, resultProc, userDataPtr)
char *hostName;
struct returnRec *returnRecPtr;
long resultProc;
char *userDataPtr;
{
if (dnr == NULL)
/* resolver not loaded error */
return(notOpenErr);
return((*dnr)((long) MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
}
pascal void resolved(hostinfo, userdata)
struct hostInfo * hostinfo;
char * userdata;
{
unsigned long oldA5;
oldA5 = getmyA5();
nameresolved = hostinfo->rtnCode;
switch (hostinfo->rtnCode) {
case 0: {
/* OK, I presume */
nameresolved = 1;
setA5(oldA5);
return;
}
case cacheFault: {
/* address not in cache, wait for resolver */
setA5(oldA5);
return;
}
}
setA5(oldA5);
}
#endif
/* save host address resource (a C string) in the current resource file */
savehostres(twp)
struct winds * twp;
{
long len;
Handle ohlasthost;
if (twp->hlasthost == NULL)
return(-1);
ohlasthost = twp->hlasthost;
if ( (twp->hlasthost = Get1Resource('LHST', LASTHOSTID) ) != NULL) {
killhost(twp);
}
len = GetHandleSize(ohlasthost);
twp->hlasthost = NewHandle((long) len);
strcpy(*twp->hlasthost, *ohlasthost);
DisposHandle(ohlasthost);
AddResource(twp->hlasthost, 'LHST', LASTHOSTID, "\P");
if (ResError()) {
error("Can't save TCP/IP Address");
return(-1);
}
else {
UpdateResFile(HomeResFile(twp->hlasthost));
DetachResource(twp->hlasthost);
}
}
killhost(twp)
struct winds * twp;
{
int hhosthome;
hhosthome = HomeResFile(twp->hlasthost);
RmveResource(twp->hlasthost);
if (ResError())
error("No host name resource kill");
UpdateResFile(hhosthome);
DisposHandle(twp->hlasthost);
}